#ifndef _IM_SERVER_MESSAGE_DB_WRAPPER_H_
#define _IM_SERVER_MESSAGE_DB_WRAPPER_H_

#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include "database/simple_db_pool.h"
#include "base/singleton.h"
#include "base/config_reader.h"
#include "message_service_handler.h"

namespace imserver {

class MessageDBWrapper : public base::Singleton<MessageDBWrapper> {

public:
  static const int MESSAGE_P2P_INDEX_DB_MOD;
  static const int MESSAGE_GROUP_INDEX_DB_MOD;
  static const int MESSAGE_ENTITY_DB_MOD;

  ~MessageDBWrapper() {
    if (conn_pool_) {
      delete conn_pool_;
    }
  }

  bool select_tb_message_id_seq(int64_t& seq);
  bool update_tb_message_id_seq();

  bool select_tb_dialogue_id_seq(int64_t& seq);
  bool update_tb_dialogue_id_seq();
  //按uid1和uid2取他们组成的dialogue的id
  bool select_tb_dialogue(int64_t uid1, int64_t uid2, int64_t& dialogue_id);
  bool select_tb_dialogue(int64_t uid1, int64_t last_msg_id, std::set<int64_t>& dialogue_ids);
  bool update_tb_dialogue(int64_t dialogue_id, int64_t uid1, int64_t uid2, int64_t last_msg_id);

  // 将message插入tb_message_entity（按dialogue_id散表）
  bool insert_tb_message_entity(const ImMessage& message);
  // 按msgid取消息本体，带上dialogue_id是为了方便定位消息位于哪张表
  bool select_tb_message_entity(int64_t uid, const std::map<int64_t, int64_t>& msgid_dialogid, std::map<int64_t, ImMessage>& res);
  
  // 如果message是P2P类消息，插入tb_p2p_message_index（按dialogue_id散表）
  bool insert_tb_p2p_message_index(const ImMessage& message);
  // 获取指定的各个dialogue中发给uid的消息指定flag位未设置的消息数量，以及最新msg的id
  bool select_tb_p2p_message_index_u(int64_t uid, const std::set<int64_t>& dialogue_ids, uint32_t unset_flag,
      std::map<int64_t, std::pair<int32_t, int64_t> >& res);
  // 获取指定dialogue中早于min_msg_id的limit条消息
  bool select_tb_p2p_message_index_o(int64_t uid, int64_t dialogue_id, int64_t min_msg_id, int32_t limit,
      std::set<int64_t>& msgid_res);
  // 获取指定dialogue中晚于max_msg_id的limit条消息
  bool select_tb_p2p_message_index_n(int64_t uid, int64_t dialogue_id, int64_t max_msg_id, int32_t limit,
      std::set<int64_t>& msgid_res);
  // 将指定dialogue中发给uid的id小于等于max_msgid的所有消息，根据set_flag设置read_status,receive_status
  bool update_tb_p2p_message_index(int64_t uid, int64_t dialogue_id, int64_t max_msgid, uint32_t set_flag);

  // 如果message是group类消息，插入tb_group_message_index（按group_id散表）
  bool insert_tb_group_message_index(const ImMessage& message);
  // 获取指定group中发给uid的id比last_read_msgid大的消息条数以及最新的msg的id
  bool select_tb_group_message_index_u(int64_t uid, int64_t group_id, int64_t last_read_msgid, int32_t& unread_count, 
      int64_t& max_msgid);
  // 获取指定group中早于min_msg_id的limit条消息
  bool select_tb_group_message_index_o(int64_t uid, int64_t group_id, int64_t min_msg_id, int32_t limit,
      std::set<int64_t>& msgid_res);
  // 获取指定group中晚于max_msg_id的limit条消息
  bool select_tb_group_message_index_n(int64_t uid, int64_t group_id, int64_t max_msg_id, int32_t limit,
      std::set<int64_t>& msgid_res);
  // 设置在指定group中uid读过的最大msgid
  bool update_tb_group_message_view_record(int64_t group_id, int64_t uid, int64_t last_read_msgid);
  bool select_tb_group_message_view_record(int64_t group_id, int64_t uid, int64_t& last_read_msgid);

private:
  friend class base::Singleton<MessageDBWrapper>;

  MessageDBWrapper() {
    ConfigReader cfg("../conf/message_service.conf");
    std::string database = "DB_MESSAGE";
    std::string addr = cfg.Get("DB_MESSAGE", "addr");
    std::string user = cfg.Get("DB_MESSAGE", "user");
    std::string pwd = cfg.Get("DB_MESSAGE", "pwd");
    conn_pool_ = 
        //boost::shared_ptr<base::SimpleConnectionPool>(
        new base::SimpleConnectionPool(database.c_str(), addr.c_str(), user.c_str(), pwd.c_str());//);
  }

  //boost::shared_ptr<base::SimpleConnectionPool> conn_pool_;
  base::SimpleConnectionPool* conn_pool_;
};

}

#endif // _IM_SERVER_MESSAGE_DB_WRAPPER_H_
